---
title: "Manually emitting messages"
icon: "lucide/Radio"
---
import InstallSDKSnippet from "@/snippets/install-sdk.mdx"
import RunAndConnect from "@/snippets/integrations/langgraph/run-and-connect.mdx"

While most agent interactions happen automatically through shared state updates as the agent runs, you can also **manually send messages from within your agent code** to provide immediate feedback to users.

<video src="https://cdn.copilotkit.ai/docs/copilotkit/images/coagents/emit-messages.mp4" className="rounded-lg shadow-xl" loop playsInline controls autoPlay muted />
<Callout>
    This video shows the result of `npx copilotkit@latest init` with the [implementation](#implementation) section applied to it!
</Callout>

## What is this?

In LangGraph, messages are only emitted when a node is completed. CopilotKit allows you to manually emit messages
in the middle of a node's execution to provide immediate feedback to the user.

## When should I use this?

Manually emitted messages are great for **when you don't want to wait for the node** to complete **and you**:
- Have a long running task that you want to provide feedback on
- Want to provide a status update to the user
- Want to provide a warning or error message

## Implementation

<Steps>
    <Step>
        ### Run and connect your agent
       <RunAndConnect components={props.components} />
    </Step>
    <Step>
        ### Install the CopilotKit SDK
        <InstallSDKSnippet components={props.components}/>
    </Step>
    <Step>
        ### Manually emit a message
        The `copilotkit_emit_message` method allows you to emit messages early in a node's execution to communicate status updates to the user. This is particularly useful for long running tasks.

        <Tabs groupId="language_langgraph_agent" items={['Python', 'TypeScript']} default="Python" persist>
            <Tab value="Python">
                ```python
                from langchain_core.messages import SystemMessage, AIMessage
                from langchain_openai import ChatOpenAI
                from langchain_core.runnables import RunnableConfig
                from copilotkit.langgraph import copilotkit_emit_message # [!code highlight]
                # ...

                async def chat_node(state: AgentState, config: RunnableConfig):
                    model = ChatOpenAI(model="gpt-4o")

                    # [!code highlight:2]
                    intermediate_message = "Thinking really hard..."
                    await copilotkit_emit_message(config, intermediate_message)

                    # simulate a long running task
                    await asyncio.sleep(2)

                    response = await model.ainvoke([
                        SystemMessage(content="You are a helpful assistant."),
                        *state["messages"]
                    ], config)

                    return Command(
                        goto=END,
                        update={
                            # Make sure to include the emitted message in the messages history # [!code highlight:2]
                            "messages": [AIMessage(content=intermediate_message), response]
                        }
                    )
                ```
            </Tab>
            <Tab value="TypeScript">
                ```typescript
                import { AIMessage, SystemMessage } from "@langchain/core/messages";
                import { ChatOpenAI } from "@langchain/openai";
                import { RunnableConfig } from "@langchain/core/runnables";
                import { copilotkitEmitMessage } from "@copilotkit/sdk-js/langgraph"; // [!code highlight]
                // ...

                async function chat_node(state: AgentState, config: RunnableConfig) {
                    const model = new ChatOpenAI({ model: "gpt-4o" });

                    // [!code highlight:2]
                    const intermediateMessage = "Thinking really hard...";
                    await copilotkitEmitMessage(config, intermediateMessage);

                    // simulate a long-running task
                    await new Promise(resolve => setTimeout(resolve, 2000));

                    const response = await model.invoke([
                        new SystemMessage({content: "You are a helpful assistant."}),
                        ...state.messages
                    ], config);

                    return {
                        // [!code highlight:2]
                        // Make sure to include the emitted message in the messages history
                        messages: [new AIMessage(intermediateMessage), response],
                    };
                }
                ```
            </Tab>
        </Tabs>
    </Step>
    <Step>
        ### Give it a try!
        Now when you talk to your agent you'll notice that it immediately responds with the message "Thinking really hard..."
        before giving you a response 2 seconds later.
    </Step>
</Steps>
